/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 * 
 * Thread.getCurrentThread().getID()
 * ConcurrentHashSet
 */
package vue;

import calcul.Fichiers_log;
import calcul.MonteCarloAbstract;
import calcul.MonteCarloMulti;
import calcul.MonteCarloSingle;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Hashtable;
import java.util.Observable;
import java.util.Observer;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import modele.Modele;
import modele.SetParams;

/**
 * Vue.
 * Les donnees (modele) sont fixes et non modifiables une fois chargees. C'est pourquoi
 * je ne me suis pas concentre sur une separation MVC (ni une implementation Observer/Observable, inutile
 * ici car le modele ne change pas).
 * @author Jo
 */
public class Fenetre<T extends MonteCarloAbstract> extends JFrame implements Observer{
    
    Modele donnees;
    
    JLabel labelIndic, labelResultat, labelDuree;
    JCheckBox multithread_onOff_checkbox;
    JTextField nSimus_textfield;
    JButton bouton;
    JProgressBar progressBar;
    JSlider slider_threads;
    JComboBox choixParametres;
    
    
    /**
     * Init.
     * @param multithread Preselection pour le choix multi/single.
     */
    public Fenetre(boolean multithread) {
        super();
        
        
        donnees = new Modele();
        for (SetParams set : donnees.sets) {
            System.out.println(set.toString());
        }
        Fichiers_log.viderFichierLog(Fichiers_log.Benchmark.SINGLE_MULTI);
        Fichiers_log.viderFichierLog(Fichiers_log.Benchmark.TIME_THREADS);
        
        
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        } catch (Exception e) { }
        
        setSize(600, 350);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Monte Carlo");
        //setResizable(false);
        setLocationRelativeTo(null);
        initGUI(multithread);
        setVisible(true);
    }
    
    private void initGUI(boolean multithread){
        multithread_onOff_checkbox = new JCheckBox("Multi-thread", multithread);
        slider_threads = new JSlider(SwingConstants.HORIZONTAL, 0, 10, 0);
        nSimus_textfield = new JTextField("100000");
        
        /*
         * Menu
         */
        String[] args = {"a","b","c","d","e"};
        JMenuBar menuBar = new JMenuBar();
        JMenu menuCharger = new JMenu("Charger parametres");
        
        for (int i = 0; i < 5; i++) {
            JMenuItem item = new JMenuItem((i+1)+" : "+args[i]);
            menuCharger.add(item);
        }
        
        //menuBar.add(menuCharger);
        this.setJMenuBar(menuBar);
        
        
        /*
         * Initialisations
         */
        JPanel panelCentre = new JPanel();
        JPanel panelCentreCentre = new JPanel();
        JPanel panelDuBouton = new JPanel();
        JPanel panelGauche = new JPanel();
        JPanel panelDroite = new JPanel();
        
        labelIndic = new JLabel("Bienvenue !");
        labelResultat = new JLabel(" ");
        labelDuree = new JLabel(" ");
        
        labelIndic.setFont(new Font("Arial", NORMAL, 12));
        labelResultat.setFont(new Font("Arial", NORMAL, 16));
        labelDuree.setFont(new Font("Arial", NORMAL, 12));
        
        
        /*
         * Action sur le bouton
         */
        bouton = new JButton("lancer!");
        bouton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                /*
                 * Changements GUI
                 */
                //if(multithread) progressBar.setIndeterminate(true);
                bouton.setEnabled(false);
                labelIndic.setText("Calcul en cours");
                labelResultat.setText(" ");
                labelDuree.setText(" ");
                
                /*
                 * Lancement du calcul sur un thread a part, pour avoir une GUI reactive
                 */
                int nSimus = Integer.valueOf( nSimus_textfield.getText() );
                
                SetParams set = (SetParams) choixParametres.getSelectedItem();
                double S=set.S, X=set.X, T=set.T, r=set.r, b=set.b, v=set.v;
                int nSteps = set.nSteps;
                
                MonteCarloAbstract calculator;
                if(multithread_onOff_checkbox.isSelected()) {
                    calculator = new MonteCarloMulti(S, X, T, r, b, v, nSteps, nSimus, slider_threads.getValue());
                }
                else {
                    calculator = new MonteCarloSingle(S, X, T, r, b, v, nSteps, nSimus);
                }
                calculator.addObserver(Fenetre.this);
                Thread thread_calculer = new Thread(calculator);
                thread_calculer.start();
            }
        });
        
        /*
         * Bouton et Progressbar
         */
        int marge=5;
        progressBar = new JProgressBar();
        ((JComponent)this.getContentPane()).setBorder(BorderFactory.createEmptyBorder(marge, marge, marge, marge));
        
        panelDuBouton.setLayout(new BorderLayout());
        panelDuBouton.setBorder(BorderFactory.createEmptyBorder(marge, marge, marge, marge));
        panelDuBouton.add(bouton, BorderLayout.LINE_END);
        
        
        /*
         * Panel gauche
         */
        panelGauche.setLayout(new BoxLayout(panelGauche, BoxLayout.PAGE_AXIS));
        panelGauche.add(labelIndic);
        panelGauche.add(labelResultat);
        panelGauche.add(Box.createRigidArea(new Dimension(0, 8)));
        panelGauche.add(labelDuree);
        
        multithread_onOff_checkbox.setAlignmentX( Component.LEFT_ALIGNMENT );
        nSimus_textfield.setMaximumSize(new Dimension(80, 20));
        nSimus_textfield.setHorizontalAlignment(JTextField.RIGHT);
            JPanel panSimus = new JPanel();
            panSimus.setLayout(new BoxLayout(panSimus, BoxLayout.X_AXIS));
            panSimus.add(nSimus_textfield);
            panSimus.add(new JLabel(" simulations"));
        panSimus.setAlignmentX( Component.LEFT_ALIGNMENT );
        slider_threads.setAlignmentX( Component.LEFT_ALIGNMENT );
        panelDroite.setBorder(BorderFactory.createCompoundBorder(new Bordure(), BorderFactory.createEmptyBorder(0, 10, 0, 0)));
        
        
        
        /*
         * Checkbox
         */
        multithread_onOff_checkbox.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                if( multithread_onOff_checkbox.isSelected() ){
                    slider_threads.setEnabled(true);
                }
                else{
                    slider_threads.setEnabled(false);
                }
            }
        });
        
        /*
         * Slider
         */
        slider_threads.setBorder(BorderFactory.createTitledBorder("Nombre de threads"));
        Hashtable labelTable = new Hashtable();
        labelTable.put( new Integer( 0 ), new JLabel("Auto") );
        labelTable.put( new Integer( 1 ), new JLabel("1") );
        labelTable.put( new Integer( 2 ), new JLabel("2") );
        labelTable.put( new Integer( 4 ), new JLabel("4") );
        labelTable.put( new Integer( 8 ), new JLabel("8") );
        labelTable.put( new Integer( 12 ), new JLabel("12") );
        slider_threads.setLabelTable( labelTable );
        slider_threads.setSnapToTicks(true);
        slider_threads.setMinorTickSpacing(1);
        slider_threads.setMajorTickSpacing(4);
        slider_threads.setPaintTicks(true);
        slider_threads.setPaintLabels(true);
        slider_threads.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                System.out.println(slider_threads.getValue());
            }
        });
        
        /*
         * Liste parametres
         */
        choixParametres = new JComboBox();
        choixParametres.setModel(donnees);
        choixParametres.setSelectedItem(donnees.getElementAt(0));
        JPanel panChoix = new JPanel();
        panChoix.setLayout(new BoxLayout(panChoix, BoxLayout.X_AXIS));
        panChoix.add(choixParametres);
        panChoix.setAlignmentX( Component.LEFT_ALIGNMENT );
        choixParametres.setMaximumSize(new Dimension(choixParametres.getMaximumSize().width, 20));
        panChoix.setBorder(BorderFactory.createTitledBorder("Parametres"));
        
        
        choixParametres.setAlignmentX( Component.LEFT_ALIGNMENT );
        /*
         * Panel droite
         */
        panelDroite.setLayout(new BoxLayout(panelDroite, BoxLayout.PAGE_AXIS));
        panelDroite.add(multithread_onOff_checkbox);
        panelDroite.add(Box.createRigidArea(new Dimension(0, 8)));
        panelDroite.add(slider_threads);
        panelDroite.add(Box.createRigidArea(new Dimension(0, 16)));
        panelDroite.add(panSimus);
        panelDroite.add(Box.createRigidArea(new Dimension(0, 8)));
        panelDroite.add(panChoix);
        
        
        /*
         * Assemblages
         */
        panelCentreCentre.setLayout(new GridLayout(1, 2));
        panelCentreCentre.add(panelGauche);
        panelCentreCentre.add(panelDroite);
        
        panelCentre.setLayout(new BorderLayout());
        panelCentre.add(panelCentreCentre, BorderLayout.CENTER);
        panelCentre.add(panelDuBouton, BorderLayout.PAGE_END);
        
        this.getContentPane().setLayout(new BorderLayout());
        this.getContentPane().add(progressBar, BorderLayout.PAGE_END);
        this.getContentPane().add(panelCentre, BorderLayout.CENTER);
    }
    
    /**
     * Maj de la barre de progression ou affichage du resultat final.
     * @param o
     * @param arg 
     */
    @Override
    public void update(Observable o, Object arg) {
        ObjetEchange obj = (ObjetEchange)arg;
        
        if(obj.finished){
            progressBar.setIndeterminate(false);
            progressBar.setValue(progressBar.getMaximum());//ajouted
            bouton.setEnabled(true);
            
            labelIndic.setText("Resultat :");
            labelResultat.setText(""+obj.res + " $");
            labelDuree.setText("Duree : " + obj.duree + " ms");
        }
        else{
            int temp = (int) (progressBar.getMaximum()*obj.pourcent);
            progressBar.setValue(temp);
        }
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        //true pour le multi-thread
        new Fenetre(true);
    }
    
}
